package com.zxpt.quetion.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.zxpt.quetion.mappervo.*;
import com.zxpt.quetion.pojo.QuestionItem;
import com.zxpt.quetion.pojovo.QuMdItVo;
import com.zxpt.quetion.pojovo.QuestionItemVo;
import com.zxpt.quetion.pojovo.QuestionMouldVo;
import com.zxpt.quetion.pojovo.QuestionOptionsVo;
import com.zxpt.quetion.service.IQuestionItemService;
import com.zxpt.quetion.service.IQuestionOptionsService;
import com.zxpt.quetion.utils.JsonMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.PageHelper;

import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import  com.zxpt.quetion.utils.Query;
import  com.zxpt.quetion.utils.CreateQueryConditionUtil;
import  com.zxpt.quetion.utils.SqlUtil;
import org.springframework.util.StringUtils;

/**
* 所在包：com.zxpt.quetion.service.impl.QuestionItemServiceImpl
* 文件名：QuestionItemServiceImpl
* 版权：稻草人.
* 描述：
* 修改人：rmk
* 修改时间：
*/
@Service
@Transactional
@Slf4j
public class QuestionItemServiceImpl implements IQuestionItemService {

    @Resource
    private QuestionItemMapperVo questionItemMapperVo;
    @Resource
    private QuMdItMapperVo quMdItMapperVo;
    @Resource
    private IQuestionOptionsService optionsService;
    @Resource
    private QuestionMouldMapperVo questionMouldMapperVo;


    @Override
    public PageInfo<QuestionItemVo> getPage (Map<String, Object> queryMap, Integer page, Integer rows) {
        Query query = CreateQueryConditionUtil.createCondition(queryMap);
        PageHelper.startPage(page, rows);
        List<QuestionItemVo> list = questionItemMapperVo.getPage(query.getSql(), queryMap);
        PageInfo<QuestionItemVo> pageInfo = new PageInfo(list);
        return pageInfo;
    }

    @Override
    public QuestionItemVo getById(String id) {
        QuestionItemVo questionItemVo = questionItemMapperVo.getById(id);
        return questionItemVo;
    }


    @Override
    public List<QuestionItemVo> getByMIdUid(Map<String, Object> remap) {
        List<QuestionItemVo> base_que_list =  questionItemMapperVo.getByMId(remap);
        List<QuestionItemVo> chained_list=base_que_list.stream().filter(x -> "chained".equals(x.getType())).collect(Collectors.toList());
        List<QuestionItemVo> no_chained_list=base_que_list.stream().filter(x -> !"chained".equals(x.getType())).collect(Collectors.toList());
        chained_list = doChainedList(chained_list);
        base_que_list = (List<QuestionItemVo>) CollectionUtils.union(chained_list, no_chained_list);

        if(remap.containsKey("uid")){
            Map<String,Object> queryMap = new HashMap<>();
            queryMap.put("qmi__mouldId__equal",remap.get("mid"));
            queryMap.put("type__equal","head");
            Query query = CreateQueryConditionUtil.createCondition(queryMap);
            List<QuestionItemVo> head_list = questionItemMapperVo.getPage(query.getSql(),queryMap);
            base_que_list = (List<QuestionItemVo>) CollectionUtils.union(base_que_list, head_list);
        }
        base_que_list = base_que_list.stream()
                .sorted(Comparator.comparing(QuestionItemVo::getRealSort)).collect(Collectors.toList());
        return base_que_list;
    }

    private List<QuestionItemVo> doChainedList(List<QuestionItemVo> chained_list){
        chained_list.forEach(x ->{
            x.setOptions(haveChildren(x.getOptions()));
        });
        return chained_list;
    }

    private List<QuestionOptionsVo> haveChildren(List<QuestionOptionsVo> allop){
        List<QuestionOptionsVo> root_list=allop.stream().filter(x -> "#".equals(x.getPid())).collect(Collectors.toList());
        root_list.forEach(x ->{
            x.setChildren(getChildren( allop,x.getId()));
        });
        return root_list;
    }
    private List<QuestionOptionsVo> getChildren(List<QuestionOptionsVo> allop,String pid){
        List<QuestionOptionsVo> children_list=allop.stream().filter(x -> pid.equals(x.getPid())).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(children_list)){
            children_list.forEach(y ->{
                y.setChildren(getChildren(allop,y.getId()));
            });
        }else{
            children_list = null;
        }
        return children_list;
    }

    @Override
    public void addOrUpdate(Map<String, Object> remap) {
        String mid = remap.get("mid").toString();
        String jsonS_ques = JsonMapper.obj2String(remap.get("gotoUpDataQuestion"));
        List<QuestionItemVo> ques= JsonMapper.string2Obj(jsonS_ques,new TypeReference<List<QuestionItemVo>>() {});

        List<QuestionItemVo> inset_ques= ques.stream().filter(x -> x.getId() == null).collect(Collectors.toList());
        List<QuestionItemVo> update_ques= ques.stream().filter(x -> x.getId() != null).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(inset_ques)){
            add( inset_ques, mid);
        }
        if(CollectionUtils.isNotEmpty(update_ques)){
            update( update_ques, mid);
        }
        QuestionMouldVo questionMouldVo = questionMouldMapperVo.getById(mid);
        questionMouldVo.setAnswerCount(ques.size());
        SqlUtil<QuestionMouldVo> sqlUtil = new SqlUtil<>();
        String sql = sqlUtil.createUpdateSelectiveSql(QuestionMouldVo.class, questionMouldVo);
        questionMouldMapperVo.updateSelective(questionMouldVo, sql);
    }


    private void add(List<QuestionItemVo> inset_ques,String mid) {
        inset_ques.forEach(x ->{
            //问题表
            SqlUtil<QuestionItemVo> sqlUtil = new SqlUtil<>();
            String sql = sqlUtil.createInsertSql(QuestionItemVo.class, x);
            questionItemMapperVo.insertSelective(x, sql);
            String queItemId = x.getId();
            //问卷和问题中间表
            QuMdItVo quMdItVo = new QuMdItVo();
            quMdItVo.setMouldId(mid);
            quMdItVo.setItemId(queItemId);
            quMdItVo.setRealSort(x.getRealSort());
            quMdItVo.setViewSort(x.getViewSort());
            SqlUtil<QuMdItVo> sqlUtil_MdIt = new SqlUtil<>();
            sql = sqlUtil_MdIt.createInsertSql(QuMdItVo.class, quMdItVo);
            quMdItMapperVo.insertSelective(quMdItVo, sql);
            //1.选项表  2.问题和选项中间表
            List<QuestionOptionsVo>  ops=x.getOptions();
            if(CollectionUtils.isNotEmpty(ops)){
                for(int i =0;i<ops.size();i++){
                    QuestionOptionsVo questionOptionsVo = ops.get(i);
                    optionsService.add(questionOptionsVo,queItemId,i);
                }
            }

        });

    }

    private void update(List<QuestionItemVo> update_ques,String mid) {
        update_ques.forEach(x ->{
            //问题表
            SqlUtil<QuestionItemVo> sqlUtil = new SqlUtil<>();
            String sql = sqlUtil.createUpdateSelectiveSql(QuestionItemVo.class, x);
            questionItemMapperVo.updateSelective(x, sql);
            String queItemId = x.getId();
            //问卷和问题中间表
            Map<String,String> it_op_map = new HashMap<>();
            it_op_map.put("mould_id",mid);
            it_op_map.put("item_id",queItemId);
            QuMdItVo quMdItVo = new QuMdItVo();
            quMdItVo.setRealSort(x.getRealSort());
            quMdItVo.setViewSort(x.getViewSort());
            SqlUtil<QuMdItVo> sqlUtil_MdIt = new SqlUtil<>();
            sql = sqlUtil_MdIt.createUpdateByMap(QuMdItVo.class,quMdItVo,it_op_map);
            quMdItMapperVo.updateSelective(quMdItVo, sql);
            //1.选项表  2.问题和选项中间表
            //op有可能是新增有可能是修改
            List<QuestionOptionsVo>  ops=x.getOptions();
            if(CollectionUtils.isNotEmpty(ops)){
                for(int i =0;i<ops.size();i++){
                    QuestionOptionsVo questionOptionsVo = ops.get(i);
                    if(StringUtils.isEmpty(questionOptionsVo.getId())){
                        optionsService.add(questionOptionsVo,queItemId,i);
                    }else{
                        optionsService.update(questionOptionsVo,queItemId,i);
                    }
                }
            }
        });
    }

    @Override
    public void add(QuestionItemVo questionItemVo) {
        SqlUtil<QuestionItemVo> sqlUtil = new SqlUtil<>();
        String sql = sqlUtil.createInsertSql(QuestionItemVo.class, questionItemVo);
        questionItemMapperVo.insertSelective(questionItemVo, sql);
    }

    @Override
    public void update(QuestionItemVo questionItemVo) {
        SqlUtil<QuestionItemVo> sqlUtil = new SqlUtil<>();
        String sql = sqlUtil.createUpdateSelectiveSql(QuestionItemVo.class, questionItemVo);
        questionItemMapperVo.updateSelective(questionItemVo, sql);
    }

    @Override
    public void updateAbsolute(QuestionItemVo questionItemVo) {
        SqlUtil<QuestionItemVo> sqlUtil = new SqlUtil<>();
        String sql = sqlUtil.createUpdateAbsoluteSql(QuestionItemVo.class);
        questionItemMapperVo.updateAbsolute(questionItemVo, sql);
    }

    @Override
    public void delById(String id) {
        questionItemMapperVo.delById(id);
    }
}
